﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using StyleMVVM.Data;
#if !DOT_NET
using Windows.Foundation.Metadata;
#endif
#if NETFX_CORE
using Windows.Foundation;
using Windows.UI.Xaml;
#else
using System.Windows;

#endif

namespace StyleMVVM.View
{
	[Flags]
	public enum RelativePosition
	{
		Center = 0,
		Left = 1,
		Right = 2,
		Top = 4,
		Bottom = 8
	}

	/// <summary>
	/// The UIVisualization Service offers the ability to open popups and popup menus
	/// </summary>
	public interface IUIVisualizationService
	{
#if NETFX_CORE
	/// <summary>
	/// Opens a popup View over the specified FrameworkElement
	/// </summary>
	/// <param name="control"></param>
	/// <param name="viewName"></param>
		IAsyncAction Popup(FrameworkElement control, string viewName);

		/// <summary>
		/// Opens a new Popup View over the specified FrameworkElement using the supplied navigation parameter
		/// </summary>
		/// <param name="control"></param>
		/// <param name="viewName"></param>
		/// <param name="navigationParameter"></param>
		IAsyncAction Popup(FrameworkElement control, string viewName, object navigationParameter);

		/// <summary>
		/// Opens a new Popup View and allows you to control all aspects of how the popup is opened
		/// </summary>
		/// <param name="control"></param>
		/// <param name="viewName"></param>
		/// <param name="navigationParameter"></param>
		/// <param name="isLightDismissEnabled"></param>
		/// <param name="cancellationToken"></param>
		/// <param name="position"></param>
		/// <param name="offset"></param>
		IAsyncAction Popup(FrameworkElement control, string viewName, object navigationParameter,
			bool isLightDismissEnabled,
			ICancellationToken cancellationToken,
			RelativePosition position,
			Point offset);

		/// <summary>
		/// Opens a new poup at the specified point
		/// </summary>
		/// <param name="point"></param>
		/// <param name="viewName"></param>
		[DefaultOverload]
		IAsyncAction Popup(Point point, string viewName);

		/// <summary>
		/// Opens a new Popup at the specified point using the provided navigation parameter
		/// </summary>
		/// <param name="point"></param>
		/// <param name="viewName"></param>
		/// <param name="navigationParameter"></param>
		[DefaultOverload]
		IAsyncAction Popup(Point point, string viewName, object navigationParameter);

		/// <summary>
		/// Opens a new Popup allowing the caller to control all aspects of how the popup is opened
		/// </summary>
		/// <param name="point"></param>
		/// <param name="viewName"></param>
		/// <param name="navigationParameter"></param>
		/// <param name="isLightDismissEnabled"></param>
		/// <param name="cancellationToken"></param>
		[DefaultOverload]
		IAsyncAction Popup(Point point, string viewName, object navigationParameter,
			bool isLightDismissEnabled,
			ICancellationToken cancellationToken);

		/// <summary>
		/// Opens a new popup menu over the specified control
		/// </summary>
		/// <param name="control"></param>
		/// <param name="menuOptions"></param>
		/// <returns></returns>
		IAsyncOperation<string> PopupMenu(FrameworkElement control, params string[] menuOptions);

		/// <summary>
		/// Opens a new popup menu relative the provided FrameworkElement
		/// </summary>
		/// <param name="control"></param>
		/// <param name="position"></param>
		/// <param name="offset"></param>
		/// <param name="menuOptions"></param>
		/// <returns></returns>
		IAsyncOperation<string> PopupMenu(FrameworkElement control, RelativePosition position,
		 Point offset, params string[] menuOptions);

		/// <summary>
		/// Opens a new popup menu at the provided spot with the specified menu options
		/// </summary>
		/// <param name="point"></param>
		/// <param name="menuOptions"></param>
		/// <returns></returns>
		[DefaultOverload]
		IAsyncOperation<string> PopupMenu(Point point, params string[] menuOptions);
#else
		/// <summary>
		/// Opens a popup View over the specified FrameworkElement
		/// </summary>
		/// <param name="control"></param>
		/// <param name="viewName"></param>
		Task Popup(FrameworkElement control, string viewName);

		/// <summary>
		/// Opens a new Popup View over the specified FrameworkElement using the supplied navigation parameter
		/// </summary>
		/// <param name="control"></param>
		/// <param name="viewName"></param>
		/// <param name="navigationParameter"></param>
		Task Popup(FrameworkElement control, string viewName, object navigationParameter);

		/// <summary>
		/// Opens a new Popup View and allows you to control all aspects of how the popup is opened
		/// </summary>
		/// <param name="control"></param>
		/// <param name="viewName"></param>
		/// <param name="navigationParameter"></param>
		/// <param name="isLightDismissEnabled"></param>
		/// <param name="cancellationToken"></param>
		/// <param name="position"></param>
		/// <param name="offset"></param>
		Task Popup(FrameworkElement control,
		           string viewName,
		           object navigationParameter,
		           bool isLightDismissEnabled,
		           ICancellationToken cancellationToken,
		           RelativePosition position,
		           Point offset);

		/// <summary>
		/// Opens a new poup at the specified point
		/// </summary>
		/// <param name="point"></param>
		/// <param name="viewName"></param>
		[DefaultOverload]
		Task Popup(Point point, string viewName);

		/// <summary>
		/// Opens a new Popup at the specified point using the provided navigation parameter
		/// </summary>
		/// <param name="point"></param>
		/// <param name="viewName"></param>
		/// <param name="navigationParameter"></param>
		[DefaultOverload]
		Task Popup(Point point, string viewName, object navigationParameter);

		/// <summary>
		/// Opens a new Popup allowing the caller to control all aspects of how the popup is opened
		/// </summary>
		/// <param name="point"></param>
		/// <param name="viewName"></param>
		/// <param name="navigationParameter"></param>
		/// <param name="isLightDismissEnabled"></param>
		/// <param name="cancellationToken"></param>
		[DefaultOverload]
		Task Popup(Point point,
		           string viewName,
		           object navigationParameter,
		           bool isLightDismissEnabled,
		           ICancellationToken cancellationToken);

		/// <summary>
		/// Opens a new popup menu over the specified control
		/// </summary>
		/// <param name="control"></param>
		/// <param name="menuOptions"></param>
		/// <returns></returns>
		Task<string> PopupMenu(FrameworkElement control, params string[] menuOptions);

		/// <summary>
		/// Opens a new popup menu relative the provided FrameworkElement
		/// </summary>
		/// <param name="control"></param>
		/// <param name="position"></param>
		/// <param name="offset"></param>
		/// <param name="menuOptions"></param>
		/// <returns></returns>
		Task<string> PopupMenu(FrameworkElement control,
		                       RelativePosition position,
		                       Point offset,
		                       params string[] menuOptions);

		/// <summary>
		/// Opens a new popup menu at the provided spot with the specified menu options
		/// </summary>
		/// <param name="point"></param>
		/// <param name="menuOptions"></param>
		/// <returns></returns>
		[DefaultOverload]
		Task<string> PopupMenu(Point point, params string[] menuOptions);
#endif

#if DOT_NET

	/// <summary>
	/// Finds an exported window under the provided name and opens it
	/// </summary>
	/// <param name="windowName">export name of the window</param>
	/// <param name="navigationParameter">navigation parameter to be passed to the window</param>
	/// <param name="showDialog">call ShowDialog instead of Show</param>
	/// <param name="owner">set the owner property to the main window</param>
	/// <param name="startupLocation">sets the startup location for the control</param>
	/// <param name="startupPoint">startup point if the window is in manual mode</param>
	/// <returns>returns a task that completes when the window closes, you should wait on because it can throw exception if window was not found.</returns>
		Task OpenWindow(string windowName,
		                object navigationParameter = null,
		                bool showDialog = false,
		                bool owner = true,
		                WindowStartupLocation? startupLocation = WindowStartupLocation.CenterOwner,
		                Point? startupPoint = null);

		/// <summary>
		/// Closes a window by the specified name
		/// </summary>
		/// <param name="windowName">name of the window to close</param>
		/// <returns>returns true if window is found and closed</returns>
		Task<bool> CloseWindow(string windowName);
#endif
	}
}